package com.alibaba.citrus.cr.unified.inventory.repository.impl;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.alibaba.citrus.cr.common.util.JsonUtil;
import com.alibaba.citrus.cr.unified.inventory.repository.AllocateOrderDetailReadRepository;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;

import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByIdRequest;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByIdsRequest;
import com.epoch.app.bcorder.model.dto.BaselineQueryScItemByPageRequest;
import com.epoch.app.bcorder.model.dto.BatchQueryWarehouseByIdsRequest;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.UnifiedInventoryService;
import com.epoch.app.crplatformenhance.api.customerquery.service.CustomerQueryService;
import com.epoch.app.crplatformenhance.dto.request.CustomerBatchRequest;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorder.dto.LoadAllocateApplyOrderRequest;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorder.model.AllocateApplyOrder;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorder.service.AllocateApplyOrderService;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.dto.AllocateOrderDetailLoadListRequest;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.dto.SearchResultResponse;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.model.AllocateOrderDetail;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.service.AllocateOrderDetailService;
import com.epoch.app.crunifiedinventory.dto.request.AllocateOrderDetailGetOrgRequest;
import com.epoch.app.crunifiedinventory.dto.request.AllocateOrderDetailSearchRequest;
import com.epoch.app.crunifiedinventory.dto.request.AllocateOrderDetailsQueryRequest;
import com.epoch.app.crunifiedinventory.dto.response.AllocateOrderDetailBatchGetOrgResponse;
import com.epoch.app.crunifiedinventory.dto.response.AllocateOrderDetailBatchGetScItemResponse;
import com.epoch.app.crunifiedinventory.dto.response.AllocateOrderDetailGetCustomerResponse;
import com.epoch.app.crunifiedinventory.dto.response.AllocateOrderDetailGetOrgResponse;
import com.epoch.app.crunifiedinventory.dto.response.AllocateOrderDetailGetWarehouseResponse;
import com.epoch.app.crunifiedinventory.model.dto.AllocateOrderCreateRequest;
import com.epoch.app.crunifiedinventory.model.dto.AllocateOrderDetailBatchGetOrgRequest;
import com.epoch.app.crunifiedinventory.model.dto.AllocateOrderDetailBatchGetScItemRequest;
import com.epoch.app.crunifiedinventory.model.dto.AllocateOrderDetailGetBatchCustomerRequest;
import com.epoch.app.crunifiedinventory.model.dto.AllocateOrderDetailGetBatchWarehouseRequest;
import com.epoch.app.crunifiedinventory.model.dto.AllocateOrderDetailGetCustomerRequest;
import com.epoch.app.crunifiedinventory.model.dto.AllocateOrderDetailLoadListVO;
import com.epoch.app.crunifiedinventory.model.dto.AllocateOrderScItemDetailDTO;
import com.epoch.app.crunifiedinventory.model.dto.FrozenAndUnconfirmedAmountResponse;
import com.epoch.app.crunifiedinventory.sdo.AllocateApplyOrderSDO;
import com.epoch.app.crunifiedinventory.sdo.AllocateOrderDetailSDO;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

//import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.dto.SearchResponse;

/**
 * @description:
 * @author: yuhw
 * @date: 2021年09月18日 15:49
 **/
@Component
public class AllocateOrderDetailReadRepositoryImpl implements AllocateOrderDetailReadRepository {

    @Resource
    AllocateOrderDetailService allocateOrderDetailService;
    @Resource
    BaseDataService baseDataService;
    @Resource
    AllocateApplyOrderService allocateApplyOrderService;
    @Resource
    UnifiedInventoryService unifiedInventoryService;
    @Resource
    CustomerQueryService customerQueryService;

    @Override
    public List<AllocateOrderDetailSDO> query(AllocateOrderDetailsQueryRequest request) {
        AllocateOrderDetailLoadListRequest r = new AllocateOrderDetailLoadListRequest();
        r.setAllocateOrderId(Long.valueOf(request.getAllocateOrderId()));
        r.setLimit(800);
        Result<List<AllocateOrderDetail>> result =
        allocateOrderDetailService.loadAllocateOrderDetailList(r);
        List<AllocateOrderDetailSDO> sdos =
        Optional.ofNullable(result.getResult())
                .map(AllocateOrderDetailReadRepositoryImpl::convert)
                .orElse(Lists.newArrayList());
        return sdos;
    }

    @Override
    public Result<List<AllocateOrderDetailSDO>> search(AllocateOrderDetailSearchRequest request) {
        AllocateOrderDetailLoadListVO loadListVO = new AllocateOrderDetailLoadListVO();
        loadListVO.setLimit(request.getLimit());
        loadListVO.setStart(request.getStart());
        loadListVO.setAsc(false);
        loadListVO.setDir("id");
        if (request.getType() != null){
            loadListVO.setType(request.getType());
        }
        SearchResultResponse response = allocateOrderDetailService.searchResult(loadListVO);
        Result result = Result.success(JsonUtil.convertList(response.getResult(),AllocateOrderDetailSDO.class));
        result.setTotal(response.getTotal());
        return result;
    }

    @Override
    public AllocateApplyOrderSDO getAllocateApplyOrderSdo(String id) {
        LoadAllocateApplyOrderRequest request = new LoadAllocateApplyOrderRequest();
        request.setId(id);
        AllocateApplyOrder allocateApplyOrder =
        allocateApplyOrderService.loadAllocateApplyOrder(request);
        AllocateApplyOrderSDO sdo = JsonUtil.convert(allocateApplyOrder,AllocateApplyOrderSDO.class);
        return sdo;
    }


    @Override
    public List<AllocateOrderDetailBatchGetOrgResponse> batchGetOrg(AllocateOrderDetailBatchGetOrgRequest request) {
        BaselineGetOrganizationByIdsRequest r = new BaselineGetOrganizationByIdsRequest();
        if (CollectionUtils.isNotEmpty(request.getOrgIds())){
            r.setIds(request.getOrgIds());
        }
        Object obj = baseDataService.baselineGetOrganizationByIds(r);
        return convertBatchOrg(obj);
    }

    public static List<AllocateOrderDetailBatchGetOrgResponse> convertBatchOrg(Object obj){
        JSONObject o = JSONObject.parseObject(JSONObject.toJSONString(obj));
        if (o != null){
            JSONArray array = o.getJSONArray("result");
            if (array != null && array.size() > 0){
                List<AllocateOrderDetailBatchGetOrgResponse> responses = Lists.newArrayList();
                for (int i = 0; i< array.size();i++){
                    JSONObject j = array.getJSONObject(i).getJSONObject("organizationSDO");

                    AllocateOrderDetailBatchGetOrgResponse r =
                            JsonUtil.convert(j,AllocateOrderDetailBatchGetOrgResponse.class);
                    responses.add(r);
                }
                return responses;
            }
        }
        return null;
    }

    @Override
    public AllocateOrderDetailGetOrgResponse getOrg(AllocateOrderDetailGetOrgRequest request) {
        BaselineGetOrganizationByIdRequest r = new BaselineGetOrganizationByIdRequest();
        if (request.getId() != null){
            r.setId(request.getId());
        }
        Object obj = baseDataService.baselineGetOrganizationById(r);
        return convertOrg(obj);
    }

    @Override
    public List<AllocateOrderDetailGetCustomerResponse> batchGetCustomer(
        AllocateOrderDetailGetBatchCustomerRequest request) {

        CustomerBatchRequest r = new CustomerBatchRequest();
        if (CollectionUtils.isNotEmpty(request.getCustomerCodes())){
            r.setCodes(request.getCustomerCodes());
        }
        Object obj =
            customerQueryService.batchQueryCustomer(r);
        return convertBatchCustomer(obj);
    }
    public static List<AllocateOrderDetailGetCustomerResponse> convertBatchCustomer(Object obj){
        JSONArray array = JSONObject.parseObject(JSONObject.toJSONString(obj))
                .getJSONArray("result");
        if (array.size() > 0){
            List<AllocateOrderDetailGetCustomerResponse> responses = Lists.newArrayList();
            for (int i=0;i<array.size();i++){
                JSONObject j = array.getJSONObject(i);
                AllocateOrderDetailGetCustomerResponse response =
                        JSONObject.parseObject(j.toJSONString(),AllocateOrderDetailGetCustomerResponse.class);
                responses.add(response);
            }
           return responses;
        }
        return null;
    }

    @Override
    public List<AllocateOrderDetailGetWarehouseResponse> batchGetWarehouse(
        AllocateOrderDetailGetBatchWarehouseRequest request) {
        BatchQueryWarehouseByIdsRequest r = new BatchQueryWarehouseByIdsRequest();
        r.setWarehouseIds(request.getWarehouseIds());
        Object obj =
        unifiedInventoryService.batchQueryWarehouseByIds(r);
        return convertBatchWarehouse(obj);
    }
    public static List<AllocateOrderDetailGetWarehouseResponse> convertBatchWarehouse(Object obj){
        JSONArray array = JSONObject.parseObject(JSONObject.toJSONString(obj))
                .getJSONArray("result");
        if (array != null && array.size() > 0){
            List<AllocateOrderDetailGetWarehouseResponse> responses = Lists.newArrayList();
//            for (int i = 0;i<array.size();i++){
//                JSONObject j = array.getJSONObject()
//            }
            return responses = JsonUtil.convertList(array,AllocateOrderDetailGetWarehouseResponse.class);
        }
        return Collections.emptyList();
    }

    @Override
    public AllocateOrderDetailGetCustomerResponse getCustomer(AllocateOrderDetailGetCustomerRequest request) {
        CustomerBatchRequest r = new CustomerBatchRequest();
        r.setCodes(Lists.newArrayList(request.getCustomerCode()));
        Object obj =
        customerQueryService.batchQueryCustomer(r);
        return convertCustomer(obj);
    }

    public static AllocateOrderDetailGetCustomerResponse convertCustomer(Object obj){
        JSONArray array = JSONObject.parseObject(JSONObject.toJSONString(obj))
                .getJSONArray("result");
        if (array.size() > 0){
            JSONObject j = array.getJSONObject(0);
            AllocateOrderDetailGetCustomerResponse response =
            JSONObject.parseObject(j.toJSONString(),AllocateOrderDetailGetCustomerResponse.class);
            return response;
        }
        return null;
    }

    public static AllocateOrderDetailGetOrgResponse convertOrg(Object obj){
        JSONObject o = JSONObject.parseObject(JSONObject.toJSONString(obj));
        if (o != null){

            JSONObject data = o.getJSONObject("result").getJSONObject("result");
            if (data != null){
                data = data.getJSONObject("organizationSDO");
            }
            if (data != null){
                AllocateOrderDetailGetOrgResponse response = JsonUtil.convert(data,AllocateOrderDetailGetOrgResponse.class);
                return response;
            }
        }
        return null;
    }

    @Override
    public List<AllocateOrderDetailBatchGetScItemResponse> batchGetScItem(
        AllocateOrderDetailBatchGetScItemRequest request) {
        BaselineQueryScItemByPageRequest r = new BaselineQueryScItemByPageRequest();
        if (CollectionUtils.isNotEmpty(request.getScItemIdList())){
            r.setIdList(request.getScItemIdList());
        }
        Object obj = baseDataService.baselineQueryScItemByPage(r);
        List<AllocateOrderDetailBatchGetScItemResponse> responses = convert(obj);
        return responses;
    }

    public static List<AllocateOrderDetailBatchGetScItemResponse> convert(Object obj){
        String s = JSONObject.toJSONString(obj);
        JSONObject object = JSONObject.parseObject(s);
        JSONArray array =
        object.getJSONObject("result").getJSONObject("result").getJSONArray("searchResult");
        List<AllocateOrderDetailBatchGetScItemResponse> responses = Lists.newArrayList();
        if (array != null && array.size() > 0){
            for (int i =0; i< array.size();i++){
                AllocateOrderDetailBatchGetScItemResponse r = new AllocateOrderDetailBatchGetScItemResponse();
                JSONObject j = array.getJSONObject(i);
                String scItemId = j.getString("scItemId");
                String title = j.getString("title");
                String scItemCode = j.getString("outerId");
                r.setScItemId(scItemId);
                r.setTitle(title);
                r.setScItemCode(scItemCode);
                r.setFeatures(JSONObject.parseObject(j.getString("features"), Map.class));
                responses.add(r);
            }
        }
        return responses;
    }

    public static List<AllocateOrderDetailSDO> convert(List<AllocateOrderDetail> details){
        return  details.stream()
                .map(AllocateOrderDetailReadRepositoryImpl::convert)
                .collect(Collectors.toList());
    }

    public static AllocateOrderDetailSDO convert(AllocateOrderDetail detail){
        return JsonUtil.convert(detail,AllocateOrderDetailSDO.class);
    }

    @Override
    public Result<FrozenAndUnconfirmedAmountResponse> queryFrozenAndUnconfirmedAmount(String companyId) {
//        allocateOrderDetailService.queryListForStatCredit()
        return null;
    }
}
